package p15_aop初体验;

import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

/**
 * spring中，很重要的一个概念就是aop，而aop的主要实现方式就是动态代理
 * spring的aop本质就是对jdb代理(或cglib代理)的一个封装
 * 将增强的逻辑抽取出来变成Aspect，将来spring会得到这些Aspect，并与目标方法形成一个调用链对象，放在jdk代理或cglib代理的回调函数里面
 * 几个概念:
 * 1.切点:目标方法
 * 2.通知:增强的方法
 * 3.切面:切点+通知
 */
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class _1_spring的aop复习 {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(_1_spring的aop复习.class);
        MyTarget bean = context.getBean(MyTarget.class);
        bean.foo();

        //context.close();
    }

    @Component
    @Aspect
    class MyAspect {
        @Before("execution(* foo())")
        public void before() {
            System.out.println("前置通知");
        }

        @Around("execution(* foo())")
        public void around(ProceedingJoinPoint point) throws Throwable {
            System.out.println("环绕前置");
            point.proceed();
            System.out.println("环绕后置");
        }

        @After("execution(* foo())")
        public void after() {
            System.out.println("后置通知");
        }
    }

    @Component
    class MyTarget {
        public void foo() {
            System.out.println("目标类的原始方法");
        }
    }
}
